package benchmark.clients;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import protobuf.Buffers.Request;
import protobuf.Buffers.MeterReadings;
import protobuf.Buffers.Request.Interval;
import benchmark.Client;
import org.apache.log4j.Logger;

public class ProtoBufClient implements Client {

	private static final String host = "127.0.0.1";
	private static final int port = 1358;
	private InetSocketAddress address = null;
	private static final Logger protoBufLogger = Logger
			.getLogger("protobuflogger");

	private Socket socket = null;
	private InputStream in = null;
	private OutputStream out = null;

	public ProtoBufClient() {
		this(ProtoBufClient.host, ProtoBufClient.port);
	}

	public ProtoBufClient(String host, int port) {

		if(System.getenv().containsKey("READINGS_HOST")){
			host = System.getenv().get("READINGS_HOST");
		}
		
		if(System.getenv().containsKey("READINGS_PORT")){
			port = Integer.parseInt(System.getenv().get("READINGS_PORT"));
		}
		
		InetAddress hostAddr = null;
		try {
			hostAddr = InetAddress.getByName(host);
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.address = new InetSocketAddress(hostAddr, port);
		socket = new Socket();
		try {
			socket.connect(this.address);
			out = socket.getOutputStream();
			in = socket.getInputStream();

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	static private long numReadings = 0;
    static private String interval = "MINUTE";
    static
    {
    	if(System.getenv().containsKey("READINGS_NUMREADINGS")){
			numReadings = Long.parseLong(System.getenv().get("READINGS_NUMREADINGS"));
		}
    	if(System.getenv().containsKey("READINGS_INTERVAL")){
			interval = System.getenv().get("READINGS_INTERVAL");
		}
    }

	@Override
	public void sendRequest() {
		try {
			// Establish connection
			long tFrom=(int)(Math.random()*(java.lang.System.currentTimeMillis()/1000));
			long tTo = tFrom + 24 * 60 * 60;
			Request request = Request.newBuilder().setId(((int) ( Math.random() * 100000))).setInterval(Interval.valueOf(interval)).setTfrom(tFrom).setNumReadings(numReadings).build();
			long begin = System.currentTimeMillis();
			request.writeDelimitedTo(out);
			// System.out.println("Sent request for id " + request.getId());
			out.flush();

			MeterReadings readings = MeterReadings.parseDelimitedFrom(in);

			long finished = System.currentTimeMillis();
			long responseTime = (finished - begin);
			protoBufLogger.info("" + responseTime);

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void finalize() {
		// Tear down the connection
		try {
			socket.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
